/*
 * Copyright (C) 2025 ameise <ameise.wang@gmail.com> - All Rights Reserved
 *
 * This file is part of e3ds.
 *
 * e3ds is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * e3ds is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with e3ds. If not, see <https://www.gnu.org/licenses/>.
 */

package deque

import "sync"

type IDeque[T any] interface {
	PushFront(T) error
	PushFrontBatch([]T) error
	PushBack(T) error
	PushBackBatch([]T) error
	PopFront() (T, error)
	PopFrontBatch(int) ([]T, error)
	PopFrontHalf() ([]T, error)
	PopFrontAll() ([]T, error)
	PopBack() (T, error)
	PopBackBatch(int) ([]T, error)
	PopBackHalf() ([]T, error)
	PopBackAll() ([]T, error)
	IsEmpty() bool
	Size() int
}

func NewDeque[T any](cap int) IDeque[T] {
	if cap < 0 {
		panic("deque.NewDeque: cap must be >= 0")
	}
	if cap == 0 {
		return NewList[T]()
	}
	return NewRing[T](cap)
}

func NewDequeLock[T any](mu sync.Locker, cap int) IDeque[T] {
	if cap < 0 {
		panic("deque.NewDeque: cap must be >= 0")
	}
	if cap == 0 {
		return NewListLock[T](mu)
	}
	return NewRingLock[T](mu, cap)
}
